using System;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Diagnostics;

namespace Host
{
    /// <summary>
    /// Inherits from DesignSurface and hosts the RootComponent and 
    /// all other designers. It also uses loaders (BasicDesignerLoader
    /// or CodeDomDesignerLoader) when required. It also provides various
    /// services to the designers. Adds MenuCommandService which is used
    /// for Cut, Copy, Paste, etc.
    /// </summary>
    public class HostSurface : DesignSurface
    {
        private bool _createdFromFile = false;
        private Loader.BasicHostLoader _loader;
        //private ServiceImp.NameCreationServiceImpl _nameCreationService;
        private ServiceImp.DesignerSerializationServiceImpl _designerSerializationService;
        private ComponentSerializationService _codeDomComponentSerializationService;
        private ServiceImp.UndoEngineImpl _undoEngine;
        private ServiceImp.MenuCommandServiceImpl _menuCommandService;
        private ISelectionService _selectionService;

        public event EventHandler CanUndoChanged;
        public event EventHandler CanRedoChanged;
        public event EventHandler UnsavedChanged;

        public bool CreatedFromFile
        {
            get { return _createdFromFile; }
            set { _createdFromFile = value; }
        }

        public ISelectionService SelectionService
        {
            get { return _selectionService; }
            set { _selectionService = value; }
        }

        public ServiceImp.MenuCommandServiceImpl MenuCommandService
        {
            get { return _menuCommandService; }
            set { _menuCommandService = value; }
        }

        public ServiceImp.UndoEngineImpl UndoEngine
        {
            get { return _undoEngine; }
            set { _undoEngine = value; }
        }

        public HostSurface()
            : base()
        {
        }
        public HostSurface(IServiceProvider parentProvider)
            : base(parentProvider)
        {
            _menuCommandService = new ServiceImp.MenuCommandServiceImpl(this.GetService(typeof(IDesignerHost)) as IDesignerHost);
            this.AddService(typeof(IMenuCommandService), _menuCommandService);
        }

        private void InitializeServices()
        {
            try
            {
                //INameCreationService
                //_nameCreationService = new Host.ServiceImp.NameCreationServiceImpl();
                //this.AddService(typeof(INameCreationService), _nameCreationService);
                //IDesignerSerializationService
                _designerSerializationService = new Host.ServiceImp.DesignerSerializationServiceImpl(this.ServiceContainer);
                if (_designerSerializationService != null)
                {
                    this.ServiceContainer.RemoveService(typeof(IDesignerSerializationService), false);
                    this.ServiceContainer.AddService(typeof(IDesignerSerializationService), _designerSerializationService);
                }
                //CodeDomComponentSerializationService
                _codeDomComponentSerializationService = new CodeDomComponentSerializationService(this.ServiceContainer);
                if (_codeDomComponentSerializationService != null)
                {
                    //- the CodeDomComponentSerializationService is ready to be replaced
                    this.ServiceContainer.RemoveService(typeof(ComponentSerializationService), false);
                    this.ServiceContainer.AddService(typeof(ComponentSerializationService), _codeDomComponentSerializationService);
                }
                //UndoEngine
                _undoEngine = new Host.ServiceImp.UndoEngineImpl(this.ServiceContainer);
                _undoEngine.CanUndoChanged += new EventHandler(_undoEngine_CanUndoChanged);
                _undoEngine.CanRedoChanged += new EventHandler(_undoEngine_CanRedoChanged);
                //disable the UndoEngine
                _undoEngine.Enabled = false;
                if (_undoEngine != null)
                {
                    //- the UndoEngine is ready to be replaced
                    this.ServiceContainer.RemoveService(typeof(UndoEngine), false);
                    this.ServiceContainer.AddService(typeof(UndoEngine), _undoEngine);
                }
                //IMenuCommandService
                //_menuCommandService = new ServiceImp.MenuCommandServiceImpl(this.GetService(typeof(IDesignerHost)) as IDesignerHost);
                //this.AddService(typeof(IMenuCommandService), _menuCommandService);
                //IDesignerOptionService
                this.SetSnapLine(false);
            }
            catch (Exception einiser)
            {
                MessageBox.Show(einiser.Message);
            }
        }

        void _undoEngine_CanRedoChanged(object sender, EventArgs e)
        {
            CanRedoChanged(sender, e);
        }

        void _undoEngine_CanUndoChanged(object sender, EventArgs e)
        {
            CanUndoChanged(sender, e);
        }

        void BasicHostLoader_UnsavedChanged(object sender, EventArgs e)
        {
            UnsavedChanged(sender, e);
        }

        internal void Initialize()
        {

            //Control control = null;
            IDesignerHost host = (IDesignerHost)this.GetService(typeof(IDesignerHost));

            if (host == null)
                return;

            try
            {
                // Set the backcolor
                Type hostType = host.RootComponent.GetType();
                //if (hostType == typeof(Form))
                //{
                //    control = this.View as Control;
                //    control.BackColor = Color.White;
                //}
                //else if (hostType == typeof(UserControl))
                //{
                //    control = this.View as Control;
                //    control.BackColor = Color.White;
                //}
                //else if (hostType == typeof(Component))
                //{
                //    control = this.View as Control;
                //    control.BackColor = Color.FloralWhite;
                //}
                //else if (hostType == typeof(Test.NewForm))
                //{
                //    Test.NewForm control1 = this.View as Test.NewForm;
                //    //control.BackColor = Color.White;
                //}
                if (hostType == typeof(TongJi_EMS.MyRootForm))
                {
                    //Not necessary
                    //TongJi_EMS.MyRootForm control = this.View as TongJi_EMS.MyRootForm;
                }
                else
                {
                    throw new Exception("Undefined Host Type: " + hostType.ToString());
                }

                // Set SelectionService - SelectionChanged event handler
                SelectionService = (ISelectionService)(this.ServiceContainer.GetService(typeof(ISelectionService)));
                SelectionService.SelectionChanged += new EventHandler(selectionService_SelectionChanged);

                IComponentChangeService l_iccs = this.ServiceContainer.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
                l_iccs.ComponentAdded += new ComponentEventHandler(componentChangeService_ComponentAdded);
                l_iccs.ComponentRemoving += new ComponentEventHandler(componentChangeService_ComponentRemoving);

                this.Loader.UnsavedChanged += new EventHandler(BasicHostLoader_UnsavedChanged);

                this.InitializeServices();
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex.ToString());
            }
        }

        void componentChangeService_ComponentAdded(object sender, ComponentEventArgs e)
        {
            //Control l_ctr = this.View as Control;
            TongJi_EMS._TJ_Basic.TJ_BasicControl l_ec = e.Component as TongJi_EMS._TJ_Basic.TJ_BasicControl;
            TongJi_EMS._TJ_Basic.TJ_BasicLabel l_el = e.Component as TongJi_EMS._TJ_Basic.TJ_BasicLabel;
            TongJi_EMS._TJ_Basic.TJ_BasicTextBox l_etb = e.Component as TongJi_EMS._TJ_Basic.TJ_BasicTextBox;
            TongJi_EMS._TJ_Basic.TJ_BasicButton l_eb = e.Component as TongJi_EMS._TJ_Basic.TJ_BasicButton;
            TongJi_EMS._TJ_Basic.TJ_BasicComboBox l_ecbx = e.Component as TongJi_EMS._TJ_Basic.TJ_BasicComboBox;
            if (!this.CreatedFromFile)
            {
                if (l_ec != null)
                {
                    l_ec.BasicControlDesigner = TongJi_EMS._TJ_Basic.BCD_Instance.Instance.BasicControlDesigner_Instance;
                    l_ec.BasicControlDesigner.NeedToShowProperty += new EventHandler(ShowProperty);
                    l_ec.BasicControlDesigner.NeedToSetPoint += new EventHandler(SetPoint);
                }
                if (l_el != null)
                {
                    l_el.BasicControlDesigner = TongJi_EMS._TJ_Basic.BCD_Instance.Instance.BasicLabelDesigner_Instance;
                    l_el.BasicControlDesigner.NeedToShowProperty += new EventHandler(ShowProperty);
                    l_el.BasicControlDesigner.NeedToSetPoint += new EventHandler(SetPoint);
                }
                if (l_etb != null)
                {
                    l_etb.BasicControlDesigner = TongJi_EMS._TJ_Basic.BCD_Instance.Instance.BasicTextBoxDesigner_Instance;
                    l_etb.BasicControlDesigner.NeedToShowProperty += new EventHandler(ShowProperty);
                    l_etb.BasicControlDesigner.NeedToSetPoint += new EventHandler(SetPoint);
                }
                if (l_eb != null)
                {
                    l_eb.BasicControlDesigner = TongJi_EMS._TJ_Basic.BCD_Instance.Instance.BasicButtonDesigner_Instance;
                    l_eb.BasicControlDesigner.NeedToShowProperty += new EventHandler(ShowProperty);
                    l_eb.BasicControlDesigner.NeedToSetPoint += new EventHandler(SetPoint);
                }
                if (l_ecbx != null)
                {
                    l_ecbx.BasicControlDesigner = TongJi_EMS._TJ_Basic.BCD_Instance.Instance.BasicComboBoxDesigner_Instance;
                    l_ecbx.BasicControlDesigner.NeedToShowProperty += new EventHandler(ShowProperty);
                    //l_ecbx.BasicControlDesigner.NeedToSetPoint += new EventHandler(SetPoint);
                }
            }
            //Form l_f = l_ctr.Parent.Parent.FindForm();
            //Control[] l_ctr1 = l_f.Controls.Find("statusStrip1", true);
            //if (l_ctr1.Length != 0)
            //{
            //    System.Windows.Forms.StatusStrip l_ss = l_ctr1[0] as System.Windows.Forms.StatusStrip;
            //    l_ss.Items.Find("toolStripStatusLabel1", true)[0].Text = l_ec.Name + " is Added";
            //}

            //ToolStripItem l_tsi = GetStateToolStrip();
            //if (l_tsi != null & l_ec != null)
            //    l_tsi.Text = l_ec.Site.Name + " is Added";
            //else if (l_el != null)
            //    l_tsi.Text = l_el.Site.Name + " is Added";
            //else if (l_etb != null)
            //    l_tsi.Text = l_etb.Site.Name + " is Added";
        }

        void componentChangeService_ComponentRemoving(object sender, ComponentEventArgs e)
        {
            TongJi_EMS._TJ_Basic.TJ_BasicControl l_ec = e.Component as TongJi_EMS._TJ_Basic.TJ_BasicControl;
            TongJi_EMS._TJ_Basic.TJ_BasicLabel l_el = e.Component as TongJi_EMS._TJ_Basic.TJ_BasicLabel;
            if (l_ec != null)
                l_ec.BasicControlDesigner.NeedToShowProperty -= new EventHandler(ShowProperty);
            if (l_el != null)
                l_el.BasicControlDesigner.NeedToShowProperty -= new EventHandler(ShowProperty);
            ToolStripItem l_tsi = GetStateToolStrip();
            if (l_tsi != null && l_ec != null)
                l_tsi.Text = l_ec.Site.Name + " is Removed";
            else if (l_el != null)
                l_tsi.Text = l_el.Site.Name + " is Removed";
        }

        /// <summary>
        /// When the selection changes this sets the PropertyGrid's selected component 
        /// </summary>
        private void selectionService_SelectionChanged(object sender, EventArgs e)
        {
            //if (_selectionService != null)
            //{
            //    ICollection selectedComponents = _selectionService.GetSelectedComponents();
            //    PropertyGrid propertyGrid = (PropertyGrid)this.GetService(typeof(PropertyGrid));


            //    object[] comps = new object[selectedComponents.Count];
            //    int i = 0;

            //    foreach (Object o in selectedComponents)
            //    {
            //        comps[i] = o;
            //        i++;
            //    }

            //    propertyGrid.SelectedObjects = comps;
            //}

            if (_selectionService != null)
            {
                ICollection selectedComponents = _selectionService.GetSelectedComponents();

                if (selectedComponents.Count == 0)
                    return;

                object[] comps = new object[selectedComponents.Count];
                int i = 0;

                foreach (Object o in selectedComponents)
                {
                    comps[i] = o;
                    i++;
                }
                Control l_c = comps[0] as Control;

                //Control l_ctr = this.View as Control;
                //Form l_f = l_ctr.Parent.Parent.FindForm();
                //Control[] l_ctr1 = l_f.Controls.Find("statusStrip1", true);
                //if (l_ctr1.Length != 0)
                //{
                //    System.Windows.Forms.StatusStrip l_ss = l_ctr1[0] as System.Windows.Forms.StatusStrip;
                //    l_ss.Items.Find("toolStripStatusLabel1", true)[0].Text = l_c.Site.Name + " is Selected";
                //}
                ToolStripItem l_tsi = GetStateToolStrip();
                if (l_tsi != null)
                    l_tsi.Text = l_c.Site.Name + " is Selected";
            }
        }

        public void AddService(Type type, object serviceInstance)
        {
            this.ServiceContainer.AddService(type, serviceInstance);
        }

        /// <summary>
        /// Get a reference of the toolstrip on the MainDesignForm
        /// The toolstrip is used to display status of design
        /// </summary>
        /// <returns></returns>
        private ToolStripItem GetStateToolStrip()
        {
            Control l_ctr = this.View as Control;
            Form l_f = l_ctr.Parent.Parent.FindForm();
            Control[] l_ctr1 = l_f.Controls.Find("statusStrip1", true);
            if (l_ctr1.Length != 0)
            {
                System.Windows.Forms.StatusStrip l_ss = l_ctr1[0] as System.Windows.Forms.StatusStrip;
                //l_ss.Items.Find("toolStripStatusLabel1", true)[0].Text = l_c.Site.Name + " is Selected";
                return l_ss.Items.Find("toolStripStatusLabel1", true)[0];
            }
            else
                return null;
        }

        private void ShowProperty(object sender, EventArgs e)
        {
            Form l_p = TJ_MainNameSpace.ZTNameFuncs.SetDoubleClickForm(sender);
            if (l_p != null)
            {
                l_p.ShowDialog();
            }
        }

        private void SetPoint(object sender, EventArgs e)
        {
            //MessageBox.Show("To set point info for this control");
            TongJi_EMS._TJ_Basic.TJ_BasicControl l_tbc = sender as TongJi_EMS._TJ_Basic.TJ_BasicControl;
            MessageBox.Show(l_tbc.DbpointID.ToString());
        }

        /// <summary>
        /// Toggle the use of SnapLine in this DesignSurface
        /// </summary>
        /// <param name="p_state"></param>
        public void SetSnapLine(bool p_state)
        {
            IServiceContainer serviceProvider = this.GetService(typeof(IServiceContainer)) as IServiceContainer;
            DesignerOptionService opsService = serviceProvider.GetService(typeof(DesignerOptionService)) as DesignerOptionService;
            if (null != opsService)
            {
                serviceProvider.RemoveService(typeof(DesignerOptionService));
            }
            DesignerOptionService opsService2 = new ServiceImp.DesignerOptionServiceImpl(p_state);
            serviceProvider.AddService(typeof(DesignerOptionService), opsService2);
        }

        /// <summary>
        /// Perform Edit Actions such as Copy, Paste, SelectAll, Delete etc.
        /// </summary>
        /// <param name="editCommand">Representing name of the ToolStripMenu which invoke this function</param>
        public void DoEditAction(string editCommand)
        {
            switch (editCommand)
            {
                case "undoToolStripButton":
                case "undoToolStripMenuItem":
                    _undoEngine.Undo();
                    break;
                case "redoToolStripButton":
                case "redoToolStripMenuItem":
                    _undoEngine.Redo();
                    break;
                case "cutToolStripMenuItem":
                    _menuCommandService.GlobalInvoke(StandardCommands.Cut);
                    break;
                case "copyToolStripMenuItem":
                    _menuCommandService.GlobalInvoke(StandardCommands.Copy);
                    break;
                case "pasteToolStripMenuItem":
                    _menuCommandService.GlobalInvoke(StandardCommands.Paste);
                    break;
                case "delToolStripMenuItem":
                    _menuCommandService.GlobalInvoke(StandardCommands.Delete);
                    break;
                case "selectAllToolStripMenuItem":
                    _menuCommandService.GlobalInvoke(StandardCommands.SelectAll);
                    break;
                default:
                    break;
            }
        }


        /// <summary>
        /// Representing Loader of current HostSurface , the Loader is Responsible of
        /// serializing and deserializing current design , meaning saving and opening projects 
        /// </summary>
        public Loader.BasicHostLoader Loader
        {
            get
            {
                return _loader;
            }
            set
            {
                _loader = value;
            }
        }

    }// class
}// namespace
